﻿using NPOI.HSSF.UserModel;
using NPOI.SS.UserModel;
using NPOI.XSSF.UserModel;
using System.IO;

namespace Soul.XLS
{
    public class ExcelWorkbook
    {
        public ExcelFileType FileType { get; private set; }

        public IWorkbook Workbobok { get; private set; }

        public ExcelTableCollection Tables { get; } = new ExcelTableCollection();

        public ExcelWorkbook(ExcelFileType excelType = ExcelFileType.Xls)
        {
            Workbobok = CreateWorkbook(excelType);
        }

        public ExcelWorkbook(string filename)
        {
            var excelType = ExcelFileType.Xls;
            using (var fs = File.OpenRead(filename))
            {
                Workbobok = CreateWorkbook(fs, excelType);
            }
        }

        public ExcelWorkbook(Stream stream, ExcelFileType excelType = ExcelFileType.Xls)
        {
            Workbobok = CreateWorkbook(stream, excelType);
        }

        public ExcelWorkbook(IWorkbook workbook)
        {
            Workbobok = workbook;
        }

        public ISheet GetSheet(int index)
        {
            return Workbobok.GetSheetAt(index);
        }

        public ISheet GetSheet(string name)
        {
            return Workbobok.GetSheet(name);
        }

        public ISheet CreateSheet()
        {
            return Workbobok.CreateSheet();
        }

        public ISheet CreateSheet(string name)
        {
            return Workbobok.CreateSheet(name);
        }

        public virtual ExcelTable ExportTable(int sheetIndex, int firstRow = 0, int firstColumn = 0, int? columnCount = null)
        {
            var sheet = GetSheet(sheetIndex);
            var table = sheet.ExportTable(firstRow, firstColumn, columnCount);
            Tables.Add(table);
            return table;
        }

        public virtual ExcelTable ExportTable(int sheetIndex, ExcelColumnCollection columns, int firstRow = 0, int firstColumn = 0)
        {
            var sheet = GetSheet(sheetIndex);
            var table = sheet.ExportTable(columns, firstRow, firstColumn);
            Tables.Add(table);
            return table;
        }

        public virtual ExcelTable ExportTable(string sheetName, int firstRow = 0, int firstColumn = 0, int? columnCount = null)
        {
            var sheet = GetSheet(sheetName);
            var table = sheet.ExportTable(firstRow, firstColumn, columnCount);
            Tables.Add(table);
            return table;
        }

        public virtual ExcelTable ExportTable(string sheetName, ExcelColumnCollection columns, int firstRow = 0, int firstColumn = 0)
        {
            var sheet = GetSheet(sheetName);
            var table = sheet.ExportTable(columns, firstRow, firstColumn);
            Tables.Add(table);
            return table;
        }

        public void SaveToFile(string file)
        {
            using (var fs = new FileStream(file, FileMode.Create))
            {
                SaveToStream(fs);
            }
        }

        public void SaveToStream(Stream stream)
        {
            foreach (var item in Tables)
            {
                Workbobok.AddTable(item);
            }
            Workbobok.Write(stream);
        }

        public static IWorkbook CreateWorkbook(ExcelFileType fileType)
        {
            if (fileType == ExcelFileType.Xls)
            {
                return new HSSFWorkbook();
            }
            else
            {
                return new XSSFWorkbook();
            }
        }

        public static IWorkbook CreateWorkbook(Stream stream, ExcelFileType fileType)
        {
            if (fileType == ExcelFileType.Xls)
            {
                return new HSSFWorkbook(stream);
            }
            else
            {
                return new XSSFWorkbook(stream);
            }
        }
    }
}
